From: Keir Fraser Date: Tue, 31 Mar 2009 10:41:13 +0000 (+0100) Subject: vtd: fix iommu vector leak X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~13989^2~52 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=ce5ab42341d8a281416f07fdd2aa795b667bb9ec;p=xen.git vtd: fix iommu vector leak When we do Dom0 S3 for many times, iommu_set_interrupt() would fail during S3 resume because it can't obtain vector. We should not request new vector for every Dom0 S3 resume. We should re-use the same vector. Signed-off-by: Dexuan Cui --- diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 6e4d4a1afa..e2b026ca7e 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -911,6 +911,8 @@ static int iommu_alloc(struct acpi_drhd_unit *drhd) return -ENOMEM; memset(iommu, 0, sizeof(struct iommu)); + iommu->vector = -1; /* No vector assigned yet. */ + iommu->intel = alloc_intel_iommu(); if ( iommu->intel == NULL ) { @@ -1666,15 +1668,18 @@ static int init_vtd_hw(void) return -EIO; } - vector = iommu_set_interrupt(iommu); - if ( vector < 0 ) + if ( iommu->vector < 0 ) { - gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n"); - return vector; + vector = iommu_set_interrupt(iommu); + if ( vector < 0 ) + { + gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n"); + return vector; + } + iommu->vector = vector; } - dma_msi_data_init(iommu, vector); + dma_msi_data_init(iommu, iommu->vector); dma_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map))); - iommu->vector = vector; clear_fault_bits(iommu); dmar_writel(iommu->reg, DMAR_FECTL_REG, 0); diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index 37fa3c7aa8..b47049267d 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -55,7 +55,7 @@ struct iommu { spinlock_t lock; /* protect context, domain ids */ spinlock_t register_lock; /* protect iommu register handling */ u64 root_maddr; /* root entry machine address */ - unsigned int vector; + int vector; struct intel_iommu *intel; };